@tool
class_name DamageReceiver
extends Area2D



@export var target: Character
@export var disabled: bool:
    set(value):
        disabled = value
        for child in get_children():
            if child is CollisionShape2D or child is CollisionPolygon2D:
                # child.disabled = disabled
                child.set_deferred("disabled", disabled)


func _ready() -> void:
    area_entered.connect(
        func(area: Area2D) -> void:
            if area is not DamageSender: return

            var sender := area as DamageSender
            var info := sender.damage_info
            if info == null or not info.is_valid or info.damage == 0: return

            info.target = target
            
            # 自己不会对自己造成伤害，敌人不会对敌人造成伤害
            if info.source == info.target or \
                (info.source is Enemy and info.target is Enemy): 
                return
            
            # 计算攻击方向 和 命中的位置
            var result := _calc_damage_direction_and_hit_position(sender.get_collision_shapes(), get_collision_shapes())
            info.direction = result[0]
            print("damage direction: ", info.direction)

            DamageSystem.handle_damage(info)

            var pos := target.center_position() if result[1] == Constant.INVAILD_HIT_POS else result[1]
            sender.hit.emit(info, pos)
    )


# 设置节点配置警告，脚本需是工具脚本
func _get_configuration_warnings() -> PackedStringArray:
    var warnings = PackedStringArray()

    # if get_scene_file_path() == "":
    #     warnings.append("请从保存的场景实例化该节点，以确保正常工作")

    for child in get_children():
        if child is not CollisionShape2D:
            warnings.append("请使用CollisionShape2D作为子节点，以确保能可以正确获取击中的位置")
            break

    return warnings



func _calc_damage_direction_and_hit_position(
        sender_shapes: Array[CollisionShape2D], 
        receiver_shapes: Array[CollisionShape2D]) -> Array[Vector2]:
    
    var default_result: Array[Vector2] = [Vector2.ZERO, Constant.INVAILD_HIT_POS]
    if sender_shapes.is_empty() or receiver_shapes.is_empty(): return default_result
    
    var direction := Vector2.ZERO
    var pos := Constant.INVAILD_HIT_POS
    
    for ss: CollisionShape2D in sender_shapes:
        for rs: CollisionShape2D in receiver_shapes:
            if not ss.shape.collide(ss.global_transform, rs.shape, rs.global_transform): continue
            direction = ss.global_position.direction_to(rs.global_position)
            var arr := ss.shape.collide_and_get_contacts(ss.global_transform, rs.shape, rs.global_transform)
            pos = arr[0]
            return [direction, pos]
    
    return default_result


func get_collision_shape(idx: int = 0) -> CollisionShape2D:
    return get_child(idx)


func get_collision_shapes() -> Array[CollisionShape2D]:
    var list: Array[CollisionShape2D] = []
    for child in get_children():
        if child is not CollisionShape2D: continue
        list.append(child)
    return list
